<template>
<div :class="[$style.container]">
  <div :class="[$style.left]">
    <div :class="[$style.header]">
      <span>团队及成员</span>
      <div>
        <el-link type="info" :underline="false" class="mr-2" v-if="leftCheckedRows.length > 0">
          <span class="ft-sm">已选择 {{leftCheckedRows.length}} 项</span>
        </el-link>
        <el-link type="primary" :underline="false" :disabled="leftCheckedRows.length < 1" @click="onLeftBatchAdd">
          <span class="ft-sm">添加</span>
        </el-link>
        <el-link type="info" :underline="false" :disabled="leftCheckedRows.length < 1" class="ml-2" @click="onLeftClear">
          <span class="ft-sm">清空选择</span>
        </el-link>
      </div>
    </div>
    <div :class="[$style.content]">
      <team-and-member-tree :checkedRows.sync="leftCheckedRows" @add="onAdd"></team-and-member-tree>
    </div>
  </div>
  <div :class="[$style.right]">
    <div :class="[$style.header]">
      <div>
        <el-checkbox v-model="checkedAllValue" :indeterminate="checkedIndeterminateValue" class="mr-3">全部</el-checkbox>
        <span>共 {{value.length}} 项</span>
      </div>
      <div :class="[$style.rightExtra]">
        <div class="mr-3" v-if="localCheckedValue.length > 0">
          <el-link type="info" :underline="false" class="mr-3">
            <span class="ft-sm">已选择 {{localCheckedValue.length}} 项</span>
          </el-link>
          <doc-perm-group-dropdown v-model="batchUmask" :team="batchTeam"></doc-perm-group-dropdown>
        </div>

        <el-link type="primary" :underline="false" :disabled="localCheckedValue.length < 1" @click="onRightBatchRemove">
          <span class="ft-sm">移除</span>
        </el-link>
        <el-link type="info" :underline="false" :disabled="localCheckedValue.length < 1" class="ml-2" @click="onRightClear">
          <span class="ft-sm">清空选择</span>
        </el-link>
      </div>
    </div>
    <div :class="[$style.content]">
      <div :class="[$style.search]">
        <el-input v-model="keyword" prefix-icon="el-icon-search" placeholder="请输入团队或成员"></el-input>
      </div>
      <div :class="[$style.listWrap]" v-loading="loading">
        <ul :class="[$style.list]" v-if="renderedValue.length > 0">
          <li :class="[$style.item]" v-for="(row, i) in renderedValue" :key="i">
            <el-checkbox :value="getCheckedValue(row)" @input="val => setCheckedValue(row, val)"></el-checkbox>
            <span :class="[$style.text]">
              <!-- <span><el-checkbox></el-checkbox></span> -->
              <span class="ft-lg ml-2">
                <i class="el-icon-s-management" v-if="row.ownType === 'team'"></i>
                <i class="el-icon-s-custom" v-else></i>
              </span>
              <span class="ml-2"><highlight-text :text="row.ownName" :keyword="keyword"></highlight-text></span>
            </span>
            <span :class="[$style.action]">
              <doc-perm-group-dropdown v-model="row.umask" :team="row.ownType === 'team'"></doc-perm-group-dropdown>
              <el-link :underline="false" type="info" class="ml-3" @click="onRemove(row)"><span class="ft-lg"><i class="el-icon-circle-close"></i></span></el-link>
            </span>
          </li>
        </ul>
        <empty-data v-else>
          <span v-if="value.length < 1">请从左侧添加</span>
          <span v-else>无符合条件记录</span>
        </empty-data>
      </div>
    </div>
  </div>
</div>
</template>

<script lang="ts">

import { Vue, Component, Prop, Emit, Ref } from 'vue-property-decorator'
import DocPermGroupDropdown from '@/views/pages/docs/components/doc-perm-group-dropdown/index.vue'

function uniqueItems (rows: any[] = []) {
  const map = new Map<string, any>()
  rows.forEach(v => {
    map.set(v._id, v)
  })
  return Array.from(map.values())
}

@Component({
  components: { DocPermGroupDropdown }
})
export default class DocAuthorizeChooser extends Vue {
  @Prop() value!: any[]

  @Prop(Boolean) loading!: boolean

  @Emit() input (value: any[]) {}

  keyword = ''

  leftCheckedRows: any[] = []

  localCheckedValue: any[] = []

  get batchUmask () {
    const set = new Set(this.localCheckedValue.map(v => v.umask))
    return set.size === 1 ? (this.localCheckedValue[0]?.umask || 0) : 0
  }

  set batchUmask (value: number) {
    this.localCheckedValue.forEach(v => {
      v.umask = value
    })
  }

  get batchTeam () {
    return this.localCheckedValue.some(v => v.ownType === 'team')
  }

  get checkedAllValue () {
    if (this.localCheckedValue.length < 1) return false
    return this.localCheckedValue.length === this.value.length
  }

  set checkedAllValue (value: boolean) {
    if (value) {
      this.localCheckedValue = [...this.value]
    } else {
      this.localCheckedValue = []
    }
  }

  get checkedIndeterminateValue () {
    if (this.checkedAllValue) return false
    return this.localCheckedValue.length > 0
  }

  get renderedValue () {
    return this.value.filter(v => this.keyword ? (v?.ownName || '').includes(this.keyword) : true)
  }

  getCheckedValue (row: any) {
    return this.localCheckedValue.some((v: any) => v === row || v?._id === row?._id)
  }

  setCheckedValue (row: any, value: boolean) {
    const idx = this.localCheckedValue.findIndex((v: any) => v === row || v?._id === row?._id)
    if (value) {
      if (idx < 0) this.localCheckedValue.push(row)
    } else {
      if (idx >= 0) this.localCheckedValue.splice(idx, 1)
    }
  }

  genItem (row: any) {
    return { umask: 4, ownType: row.type, ownId: row.type === 'team' ? row.id : row.userId, ownName: row.label, id: row?.id, _id: row?._id }
  }

  onAdd (row: any) {
    const item = this.genItem(row)
    if (this.value.some(v => (v === item || (v?._id === item?._id)))) {
      this.$message.info('已存在列表中')
      return
    }
    this.input(uniqueItems([...(this.value || []), item]))
  }

  onLeftBatchAdd () {
    const rows = this.leftCheckedRows
    if (rows.length > 0) {
      const ret = rows.filter((v: any) => {
        return !this.value.some((w: any) => w === v || w?._id === v?._id)
      }).map((v: any) => this.genItem(v))
      if (ret.length > 0) {
        this.input(uniqueItems([...(this.value || []), ...ret]))
      }
    }
    this.onLeftClear()
  }

  onLeftClear () {
    this.leftCheckedRows = []
  }

  onRemove (row: any) {
    this.input(uniqueItems(this.value.filter(v => !(row === v || (row?._id === v?._id)))))
    const idx = this.localCheckedValue.findIndex((v: any) => v === row || v?._id === row?._id)
    if (idx >= 0) this.localCheckedValue.splice(idx, 1)
  }

  onRightBatchRemove () {
    const rows = this.localCheckedValue || []
    const ret = this.value.filter(v => !rows.some((w: any) => v === w || v?._id === w?._id))
    this.input(uniqueItems(ret))
    this.onRightClear()
  }

  onRightClear () {
    this.localCheckedValue = []
  }
}
</script>

<style lang="scss" module>
@import "~@/styles/vars.scss";

.container {
  display: flex;
}

.left {
  margin-right: 20px;
  flex: 1 1 auto;
  height: 100%;
  width: 50%;

}

.right {
  width: 50%;
  margin-left: 20px;
  flex:  1 1 auto;
  height: 100%;
}

.header {
  height: 32px;
  display: flex;
  justify-content: space-between;
}

.content {
  box-sizing: 100%;
  border: 1px solid $border-color;
  height: calc(100% - 40px);
}

.search {
  border-bottom: solid 1px $border-split-color;
  :global {
    .el-input__inner {
      border: none;
    }
  }
}

.listWrap {
  height: calc(100% - 40px - 2px);
  overflow: auto;
}

.list {
  list-style: none;
  margin: 0;
  padding: 0;
  min-height: 100%;
}

.item {
  display: flex;
  height: 40px;
  align-items: center;
  padding: 0 20px;
  justify-content: center;

  &:hover {
    background-color: $bg-body-color;
    .action {
      opacity: 1;
    }
  }
}

.text {
  flex: 1 1 auto;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.action {
  flex: 0 0 auto;
  margin-left: 12px;
  display: flex;
}

.rightExtra {
  display: flex;
  align-items: flex-start;
}

</style>
